<template>
  <div class="category-manage-layout">
    <!-- 左侧分类树区 -->
    <aside class="category-sidebar">
      <div class="panel-title">分类结构</div>
      <el-tree
        :data="categoryTree"
        :props="treeProps"
        node-key="id"
        default-expand-all
        highlight-current
        :expand-on-click-node="false"
        draggable
        @node-click="onCategoryClick"
        @node-drop="onCategoryDrop"
        class="category-tree"
      >
        <template #default="{ node, data }">
          <div class="category-node">
            <img v-if="data.logo" :src="data.logo" class="category-node-logo" />
            <el-icon v-else class="category-node-icon"><Folder /></el-icon>
            <span class="category-node-name">{{ data.name }}</span>
          </div>
          <el-button size="small" type="text" @click.stop="onEditCategory(data)">编辑</el-button>
          <el-button size="small" type="danger" @click.stop="onDeleteCategory(data)">删除</el-button>
        </template>
      </el-tree>
      <el-button type="primary" class="add-category-btn" @click="onAddCategory(null)">添加分类</el-button>
    </aside>
    <!-- 右侧详情区 -->
    <section class="category-main">
      <el-card class="category-card">
        <el-tabs v-model="activeTab">
          <el-tab-pane label="基本信息" name="base">
            <div v-if="currentCategory">
              <el-form :model="currentCategory" label-width="80px" style="max-width:400px;">
                <el-form-item label="分类Logo">
                  <div class="category-info-logo">
                    <img v-if="currentCategory.logo" :src="currentCategory.logo" class="category-info-logo-img" />
                    <el-icon v-else class="category-info-logo-icon"><Folder /></el-icon>
                    <span class="category-info-logo-text">{{ currentCategory.logo ? '已上传Logo' : '未上传Logo' }}</span>
                  </div>
                </el-form-item>
                <el-form-item label="分类名称">
                  <el-input v-model="currentCategory.name" />
                </el-form-item>
                <el-form-item label="描述">
                  <el-input v-model="currentCategory.desc" />
                </el-form-item>
                <el-form-item label="状态">
                  <el-switch v-model="currentCategory.enabled" active-text="启用" inactive-text="禁用" />
                </el-form-item>
                <el-form-item label="排序">
                  <el-input-number v-model="currentCategory.sort" :min="1" />
                </el-form-item>
                <el-form-item label="父级分类">
                  <span>{{ getParentName(currentCategory) }}</span>
                </el-form-item>
              </el-form>
            </div>
            <div v-else class="empty-tip">请选择左侧分类节点</div>
          </el-tab-pane>
          <el-tab-pane label="分类标签" name="tags">
            <div v-if="currentCategory">
              <div class="info-row" style="font-weight:600;">已分配标签：</div>
              <div style="display:flex;gap:10px;flex-wrap:wrap;margin-bottom:18px;">
                <template v-if="categoryTags[currentCategory.id] && categoryTags[currentCategory.id].length">
                  <el-tag
                    v-for="tid in categoryTags[currentCategory.id]"
                    :key="tid"
                    :color="getTagColor(tid)"
                    closable
                    @close="removeTagFromCategory(currentCategory.id, tid)"
                    style="color:#fff;font-weight:500;"
                  >{{ getTagName(tid) }}</el-tag>
                </template>
                <span v-else style="color:#aaa;">暂无标签</span>
              </div>
              <div class="info-row" style="font-weight:600;">添加标签：</div>
              <div style="display:flex;gap:10px;flex-wrap:wrap;">
                <el-tag
                  v-for="tag in availableTags(currentCategory.id)"
                  :key="tag.id"
                  :color="tag.color"
                  style="color: #fff;cursor:pointer;"
                  @click="addTagToCategory(currentCategory.id, tag.id)"
                >{{ tag.name }} <el-icon style="margin-left:4px;"><Plus /></el-icon></el-tag>
              </div>
            </div>
            <div v-else class="empty-tip">请选择左侧分类节点</div>
          </el-tab-pane>
          <el-tab-pane label="平台映射" name="mapping">
            <div v-if="currentCategory">
              <el-tabs v-model="activePlatform" type="card">
                <el-tab-pane v-for="plat in platforms" :key="plat" :label="plat" :name="plat">
                  <el-table :data="getMappingsForCurrentCategory(currentCategory.id, plat)" border stripe class="mapping-table">
                    <el-table-column prop="platformCategoryId" label="平台分类ID" width="160" />
                    <el-table-column prop="platformCategoryName" label="平台分类名称" />
                    <el-table-column label="操作" width="120">
                      <template #default="scope">
                        <el-button size="small" @click="onEditMapping(currentCategory.id, scope.row, plat)">编辑</el-button>
                        <el-button size="small" type="danger" @click="onDeleteMapping(currentCategory.id, scope.row, plat)">删除</el-button>
                      </template>
                    </el-table-column>
                  </el-table>
                  <el-button type="primary" class="add-mapping-btn" @click="onAddMapping(currentCategory.id, plat)">新增映射</el-button>
                </el-tab-pane>
              </el-tabs>
            </div>
            <div v-else class="empty-tip">请选择左侧分类节点</div>
          </el-tab-pane>
        </el-tabs>
      </el-card>
    </section>
    <!-- 分类新增/编辑弹窗 -->
    <el-dialog v-model="showCategoryDialog" :title="categoryForm.id ? '编辑分类' : '新增分类'" width="500px">
      <el-form :model="categoryForm" label-width="80px">
        <el-form-item label="分类名称"><el-input v-model="categoryForm.name" /></el-form-item>
        <el-form-item label="分类Logo">
          <el-upload
            class="category-logo-uploader"
            action="#"
            :auto-upload="false"
            :show-file-list="false"
            :on-change="handleLogoChange"
            accept="image/*"
          >
            <img v-if="categoryForm.logo" :src="categoryForm.logo" class="category-logo" />
            <el-icon v-else class="category-logo-uploader-icon"><Plus /></el-icon>
          </el-upload>
          <div class="upload-tip">建议尺寸：120x120px，支持 JPG、PNG 格式</div>
        </el-form-item>
        <el-form-item label="上级分类">
          <el-cascader v-model="categoryForm.parentIds" :options="categoryTree" :props="{ value: 'id', label: 'name', children: 'children', checkStrictly: true, emitPath: true }" clearable />
        </el-form-item>
        <el-form-item label="排序"><el-input-number v-model="categoryForm.sort" :min="1" /></el-form-item>
        <el-form-item label="状态"><el-switch v-model="categoryForm.enabled" active-text="启用" inactive-text="禁用" /></el-form-item>
        <el-form-item label="描述"><el-input v-model="categoryForm.desc" /></el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showCategoryDialog = false">取消</el-button>
        <el-button type="primary" @click="onSaveCategory">保存</el-button>
      </template>
    </el-dialog>
    <!-- 映射新增/编辑弹窗 -->
    <el-dialog v-model="showMappingDialog" :title="mappingForm.id ? '编辑映射' : '新增映射'" width="400px">
      <el-form :model="mappingForm" label-width="80px">
        <el-form-item label="平台分类">
          <el-cascader
            v-model="mappingForm.platformCategory"
            :options="getPlatformCategoryOptions(activePlatform)"
            :props="{ value: 'id', label: 'labelWithId', children: 'children', emitPath: true }"
            clearable
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showMappingDialog = false">取消</el-button>
        <el-button type="primary" @click="onSaveMapping">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { Plus, Folder } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
// mock平台自有分类树
const categoryTree = ref([
  { id: 1, name: '服装服饰', enabled: true, sort: 1, desc: '服装、服饰及相关配件', children: [
    { id: 11, name: '男装', enabled: true, sort: 1, desc: '男士服装', children: [] },
    { id: 12, name: '女装', enabled: true, sort: 2, desc: '女士服装', children: [] }
  ] },
  { id: 2, name: '电子产品', enabled: true, sort: 2, desc: '各类电子产品', children: [] },
  { id: 3, name: '书籍杂志', enabled: true, sort: 3, desc: '', children: [] },
  { id: 4, name: '家居用品', enabled: true, sort: 4, desc: '', children: [] },
  { id: 5, name: '游戏动漫', enabled: true, sort: 5, desc: '', children: [] },
  { id: 6, name: '美妆个护', enabled: true, sort: 6, desc: '', children: [] }
])
const treeProps = { label: 'name', children: 'children' }
const currentCategory = ref<any>(null)
function onCategoryClick(node: any) { currentCategory.value = node }

// 分类标签 mock 数据
const tags = [
  { id: 1, name: '新品', color: '#4361ee' },
  { id: 2, name: '热卖', color: '#e63946' },
  { id: 3, name: '限时', color: '#f59e42' },
  { id: 4, name: '进口', color: '#2dba4e' }
]
// 分类与标签的关系（categoryId: tagId[]）
const categoryTags = ref<Record<number, number[]>>({
  1: [1,2],
  11: [3],
  12: [2,4]
})
function getTagName(tid: number) {
  return tags.find(t=>t.id===tid)?.name || ''
}
function getTagColor(tid: number) {
  return tags.find(t=>t.id===tid)?.color || '#ccc'
}
function availableTags(cid: number) {
  const used = categoryTags.value[cid] || []
  return tags.filter(t=>!used.includes(t.id))
}
function addTagToCategory(cid: number, tid: number) {
  if (!categoryTags.value[cid]) categoryTags.value[cid] = []
  if (!categoryTags.value[cid].includes(tid)) categoryTags.value[cid].push(tid)
}
function removeTagFromCategory(cid: number, tid: number) {
  if (!categoryTags.value[cid]) return
  categoryTags.value[cid] = categoryTags.value[cid].filter(id=>id!==tid)
}

// 分类新增/编辑
const showCategoryDialog = ref(false)
const categoryForm = reactive({ id: undefined, name: '', logo: '', parentIds: [] as number[], sort: 1, enabled: true, desc: '' })
function handleLogoChange(file: any) {
  // mock上传，直接本地预览
  const reader = new FileReader()
  reader.onload = e => {
    categoryForm.logo = e.target?.result as string
  }
  reader.readAsDataURL(file.raw)
}

function onAddCategory(parent: any) {
  categoryForm.id = undefined
  categoryForm.name = ''
  categoryForm.logo = ''
  categoryForm.parentIds = parent ? getParentIds(parent) : []
  categoryForm.sort = 1
  categoryForm.enabled = true
  categoryForm.desc = ''
  showCategoryDialog.value = true
}
function onEditCategory(data: any) {
  categoryForm.id = data.id
  categoryForm.name = data.name
  categoryForm.logo = data.logo || ''
  categoryForm.parentIds = getParentIds(data)
  categoryForm.sort = data.sort
  categoryForm.enabled = data.enabled
  categoryForm.desc = data.desc
  showCategoryDialog.value = true
}
function onDeleteCategory(data: any) {
  // mock删除，实际需递归删除
  if (data.children && data.children.length) return alert('请先删除下级分类')
  removeCategoryById(categoryTree.value, data.id)
  if (currentCategory.value && currentCategory.value.id === data.id) currentCategory.value = null
}
function onSaveCategory() {
  if (!categoryForm.name.trim()) return;
  if (categoryForm.id) {
    // 编辑
    updateCategoryById(categoryTree.value, categoryForm.id, {
      name: categoryForm.name,
      logo: categoryForm.logo,
      desc: categoryForm.desc,
      sort: categoryForm.sort,
      enabled: categoryForm.enabled
    });
  } else {
    // 新增
    const newId = Date.now();
    const newCategory = {
      id: newId,
      name: categoryForm.name,
      logo: categoryForm.logo,
      desc: categoryForm.desc,
      sort: categoryForm.sort,
      enabled: categoryForm.enabled,
      children: []
    };
    if (categoryForm.parentIds && categoryForm.parentIds.length) {
      // 找到父节点插入
      const parentId = categoryForm.parentIds[categoryForm.parentIds.length - 1];
      const parent = findCategoryById(categoryTree.value, parentId);
      if (parent) parent.children.push(newCategory);
    } else {
      // 顶级
      categoryTree.value.push(newCategory);
    }
    // 新增后自动选中
    currentCategory.value = newCategory;
  }
  showCategoryDialog.value = false;
}
function getParentIds(node: any) {
  // 递归查找节点的父级路径
  function findParentPath(tree: any[], targetId: number, path: number[] = []): number[] | null {
    for (const item of tree) {
      if (item.id === targetId) {
        return path;
      }
      if (item.children && item.children.length) {
        const result = findParentPath(item.children, targetId, [...path, item.id]);
        if (result) return result;
      }
    }
    return null;
  }
  
  const parentPath = findParentPath(categoryTree.value, node.id);
  return parentPath || [];
}

function getParentName(node: any) {
  const parentIds = getParentIds(node);
  if (parentIds.length === 0) {
    return '无（顶级分类）';
  }
  
  // 获取父级分类名称
  function getCategoryNameById(tree: any[], id: number): string {
    for (const item of tree) {
      if (item.id === id) {
        return item.name;
      }
      if (item.children && item.children.length) {
        const name = getCategoryNameById(item.children, id);
        if (name) return name;
      }
    }
    return '';
  }
  
  const parentId = parentIds[parentIds.length - 1];
  const parentName = getCategoryNameById(categoryTree.value, parentId);
  return parentName || '未知分类';
}
function removeCategoryById(tree: any[], id: number) {
  for (let i = 0; i < tree.length; i++) {
    if (tree[i].id === id) { tree.splice(i, 1); return true }
    if (tree[i].children && tree[i].children.length) {
      if (removeCategoryById(tree[i].children, id)) return true
    }
  }
  return false
}
// 辅助方法：递归更新分类
function updateCategoryById(tree: any[], id: number, data: any) {
  for (let i = 0; i < tree.length; i++) {
    if (tree[i].id === id) {
      Object.assign(tree[i], data);
      return true;
    }
    if (tree[i].children && tree[i].children.length) {
      if (updateCategoryById(tree[i].children, id, data)) return true;
    }
  }
  return false;
}

// mock平台列表
const platforms = ['煤炉', '雅虎日拍', '雅虎闲置']
const activeTab = ref('base')
const activePlatform = ref(platforms[0])
// mock平台分类树
const platformCategories: Record<string, any[]> = {
  '煤炉': [
    { id: 'ml-1', name: '电子产品', children: [
      { id: 'ml-11', name: '手机', children: [
        { id: 'ml-111', name: '智能手机', children: [] },
        { id: 'ml-112', name: '功能机', children: [] }
      ] },
      { id: 'ml-12', name: '电脑', children: [
        { id: 'ml-121', name: '笔记本', children: [] },
        { id: 'ml-122', name: '台式机', children: [] }
      ] }
    ] },
    { id: 'ml-2', name: '服装服饰', children: [
      { id: 'ml-21', name: '男装', children: [] },
      { id: 'ml-22', name: '女装', children: [] }
    ] }
  ],
  '雅虎日拍': [
    { id: 'yh-1', name: '家电', children: [
      { id: 'yh-11', name: '电视', children: [] },
      { id: 'yh-12', name: '冰箱', children: [] }
    ] },
    { id: 'yh-2', name: '图书杂志', children: [
      { id: 'yh-21', name: '小说', children: [] },
      { id: 'yh-22', name: '漫画', children: [] }
    ] }
  ],
  '雅虎闲置': [
    { id: 'xz-1', name: '美妆', children: [
      { id: 'xz-11', name: '护肤', children: [
        { id: 'xz-111', name: '面膜', children: [] },
        { id: 'xz-112', name: '乳液', children: [] }
      ] },
      { id: 'xz-12', name: '彩妆', children: [] }
    ] },
    { id: 'xz-2', name: '运动户外', children: [
      { id: 'xz-21', name: '健身', children: [] },
      { id: 'xz-22', name: '骑行', children: [] }
    ] }
  ]
}
// 每个分类节点的映射关系（categoryId: 映射数组，含平台分类ID和名称）
const mappingsMap = ref<Record<number, any[]>>({
  1: [
    { platform: '煤炉', platformCategory: ['ml-1', 'ml-11'], platformCategoryId: 'ml-11', platformCategoryName: '手机' },
    { platform: '雅虎日拍', platformCategory: ['yh-1', 'yh-11'], platformCategoryId: 'yh-11', platformCategoryName: '电视' }
  ],
  2: [
    { platform: '雅虎闲置', platformCategory: ['xz-1', 'xz-11'], platformCategoryId: 'xz-11', platformCategoryName: '护肤' },
    { platform: '煤炉', platformCategory: ['ml-2', 'ml-21'], platformCategoryId: 'ml-21', platformCategoryName: '男装' }
  ],
  11: [
    { platform: '煤炉', platformCategory: ['ml-2', 'ml-21'], platformCategoryId: 'ml-21', platformCategoryName: '男装' }
  ],
  12: [
    { platform: '煤炉', platformCategory: ['ml-2', 'ml-22'], platformCategoryId: 'ml-22', platformCategoryName: '女装' }
  ],
  3: [
    { platform: '雅虎日拍', platformCategory: ['yh-2', 'yh-21'], platformCategoryId: 'yh-21', platformCategoryName: '小说' }
  ],
  4: [
    { platform: '雅虎闲置', platformCategory: ['xz-2', 'xz-21'], platformCategoryId: 'xz-21', platformCategoryName: '健身' }
  ]
})
// 递归查找平台分类树最后一级节点
function findLastNode(arr: any[], ids: (string|number)[]): any {
  let node = null
  let currentArr = arr
  for (const id of ids) {
    node = (currentArr || []).find(item => String(item.id) === String(id))
    if (node && node.children && node.children.length) {
      currentArr = node.children
    } else {
      break
    }
  }
  return node
}

function getMappingsForCurrentCategory(cid: number, platform: string) {
  return (mappingsMap.value[cid]||[])
    .filter(m => m.platform === platform)
    .map(m => {
      let id = m.platformCategoryId
      let name = m.platformCategoryName
      if (!id && m.platformCategory?.length) id = m.platformCategory[m.platformCategory.length-1]
      if (!name) {
        const lastNode = findLastNode(platformCategories[platform], m.platformCategory)
        name = lastNode?.name || getPlatformCategoryName(platform, m.platformCategory)
      }
      return {
        ...m,
        platformCategoryId: id,
        platformCategoryName: name
      }
    })
}
function getPlatformCategoryName(platform: string, ids: string[]) {
  let arr = platformCategories[platform];
  let names: string[] = [];
  for (const id of ids) {
    const found = arr.find(item => item.id === id);
    if (found) {
      names.push(found.name);
      arr = found.children || [];
    } else {
      break;
    }
  }
  return names.join(' / ');
}
function findCategoryById(tree: any[], id: string): any {
  for (const node of tree) {
    if (node.id === id) return node
    if (node.children && node.children.length) {
      const found = findCategoryById(node.children, id)
      if (found) return found
    }
  }
  return null
}
// 映射新增/编辑
const showMappingDialog = ref(false)
const mappingForm = reactive<{ id: any, platformCategory: any[], _cid?: number }>({ id: undefined, platformCategory: [] })
function onAddMapping(cid: number, platform: string) {
  mappingForm.id = undefined
  mappingForm.platformCategory = []
  activePlatform.value = platform
  showMappingDialog.value = true
  mappingForm._cid = cid
}
function onEditMapping(cid: number, row: any, platform: string) {
  mappingForm.id = row.id
  // 确保platformCategory是数组格式
  mappingForm.platformCategory = Array.isArray(row.platformCategory) ? [...row.platformCategory] : []
  activePlatform.value = platform
  showMappingDialog.value = true
  mappingForm._cid = cid
}
function onDeleteMapping(cid: number, row: any, platform: string) {
  ElMessageBox.confirm(
    `确定要删除映射关系"${row.platformCategoryName}"吗？`,
    '删除确认',
    {
      confirmButtonText: '确定删除',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(() => {
      const arr = mappingsMap.value[cid] || []
      const idx = arr.findIndex(m => m.id === row.id)
      if (idx !== -1) {
        arr.splice(idx, 1)
        ElMessage.success('映射关系删除成功')
      }
    })
    .catch(() => {
      // 用户取消删除，不做任何操作
    })
}
function onSaveMapping() {
  const cid = mappingForm._cid
  if (!cid) return
  if (!mappingsMap.value[cid]) mappingsMap.value[cid] = []
  if (!mappingForm.platformCategory || !mappingForm.platformCategory.length) {
    // 未选择分类不允许保存
    return
  }
  const platform = activePlatform.value
  const ids = Array.isArray(mappingForm.platformCategory) ? mappingForm.platformCategory : [mappingForm.platformCategory]
  const lastNode = findLastNode(platformCategories[platform], ids)
  const lastId = lastNode?.id || (ids.length ? ids[ids.length-1] : '')
  const lastName = lastNode?.name || ''

  if (mappingForm.id) {
    // 编辑
    const idx = mappingsMap.value[cid].findIndex(m => m.id === mappingForm.id)
    if (idx !== -1) {
      mappingsMap.value[cid][idx].platformCategory = [...ids]
      mappingsMap.value[cid][idx].platformCategoryId = lastId
      mappingsMap.value[cid][idx].platformCategoryName = lastName
    }
  } else {
    // 新增
    mappingsMap.value[cid].push({
      id: Date.now(),
      platform: activePlatform.value,
      platformCategory: [...ids],
      platformCategoryId: lastId,
      platformCategoryName: lastName
    })
  }
  showMappingDialog.value = false
}
function getPlatformCategoryOptions(platform: string) {
  // 返回平台分类树，labelWithId为“ID 名称”
  function addLabelWithId(nodes: any[]): any[] {
    return nodes.map(n => ({
      ...n,
      labelWithId: `${n.id} ${n.name}`,
      children: n.children ? addLabelWithId(n.children) : undefined
    }))
  }
  return addLabelWithId(platformCategories[platform] || [])
}

function onCategoryDrop(draggingNode: any, dropNode: any, dropType: string) {
  // 递归查找并删除拖拽节点
  function removeNode(tree: any[], id: number): any {
    for (let i = 0; i < tree.length; i++) {
      if (tree[i].id === id) {
        return tree.splice(i, 1)[0]
      }
      if (tree[i].children && tree[i].children.length) {
        const res = removeNode(tree[i].children, id)
        if (res) return res
      }
    }
    return null
  }
  // 递归查找插入位置
  function insertNode(tree: any[], node: any, targetId: number, type: string): boolean {
    for (let i = 0; i < tree.length; i++) {
      if (tree[i].id === targetId) {
        if (type === 'inner') {
          tree[i].children = tree[i].children || []
          tree[i].children.push(node)
        } else if (type === 'before') {
          tree.splice(i, 0, node)
        } else if (type === 'after') {
          tree.splice(i + 1, 0, node)
        }
        return true
      }
      if (tree[i].children && tree[i].children.length) {
        const res = insertNode(tree[i].children, node, targetId, type)
        if (res) return true
      }
    }
    return false
  }
  const dragId = draggingNode.data.id
  const dropId = dropNode.data.id
  const node = removeNode(categoryTree.value, dragId)
  if (node) {
    insertNode(categoryTree.value, node, dropId, dropType)
    // 如果当前选中的是被拖拽的节点，需要更新其引用
    if (currentCategory.value && currentCategory.value.id === dragId) {
      // 重新查找拖拽后的节点位置
      function findNodeById(tree: any[], id: number): any {
        for (const item of tree) {
          if (item.id === id) return item
          if (item.children && item.children.length) {
            const found = findNodeById(item.children, id)
            if (found) return found
          }
        }
        return null
      }
      const updatedNode = findNodeById(categoryTree.value, dragId)
      if (updatedNode) {
        currentCategory.value = updatedNode
      }
    }
  }
}
</script>

<style scoped>
.category-manage-layout {
  display: flex;
  height: 100%;
  background: #f4f7fb;
  min-height: 600px;
  border-radius: 12px;
  box-shadow: 0 2px 12px #22335411;
  padding: 24px 0 24px 24px;
}
.category-sidebar {
  width: 260px;
  background: linear-gradient(180deg, #223354 0%, #2d3a4f 100%);
  color: #e3eaf6;
  border-radius: 12px;
  box-shadow: 2px 0 8px #0001;
  padding: 24px 12px 24px 18px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  margin-right: 24px;
}
.panel-title {
  font-weight: bold;
  margin-bottom: 16px;
  font-size: 17px;
  color: #fff;
  letter-spacing: 1px;
}
.category-tree {
  background: none;
  padding: 0 0 12px 0;
  border-radius: 6px;
  min-height: 400px;
  color: #e3eaf6;
}
.add-category-btn {
  margin-top: 12px;
  width: 100%;
  border-radius: 8px;
  font-weight: 600;
  letter-spacing: 1px;
}
.category-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.category-card {
  border-radius: 14px;
  box-shadow: 0 2px 12px #22335411;
  padding: 32px 32px 24px 32px;
  min-height: 500px;
}
.info-row {
  margin-bottom: 16px;
  font-size: 15px;
  color: #223354;
}
.empty-tip {
  color: #bfcbe6;
  font-size: 15px;
  margin: 32px 0;
  text-align: center;
}
.mapping-table {
  margin-bottom: 16px;
  border-radius: 8px;
}
.add-mapping-btn {
  margin-top: 8px;
  border-radius: 8px;
  font-weight: 600;
}

/* Logo上传样式 */
.category-logo-uploader {
  display: inline-block;
}

.category-logo {
  width: 80px;
  height: 80px;
  border-radius: 8px;
  object-fit: cover;
  border: 2px solid #e4e7ed;
  cursor: pointer;
  transition: all 0.3s;
}

.category-logo:hover {
  border-color: #409eff;
  transform: scale(1.05);
}

.category-logo-uploader-icon {
  font-size: 32px;
  color: #c0c4cc;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: #f5f7fa;
  border: 2px dashed #d9d9d9;
  cursor: pointer;
  transition: all 0.3s;
}

.category-logo-uploader-icon:hover {
  border-color: #409eff;
  color: #409eff;
  background: #f0f9ff;
}

.upload-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 8px;
  line-height: 1.4;
}

/* 分类树节点样式 */
.category-node {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
}

.category-node-logo {
  width: 20px;
  height: 20px;
  border-radius: 4px;
  object-fit: cover;
  border: 1px solid #e4e7ed;
}

.category-node-icon {
  font-size: 16px;
  color: #c0c4cc;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.category-node-name {
  color: #e3eaf6;
  font-size: 14px;
}

/* 基本信息页面Logo样式 */
.category-info-logo {
  display: flex;
  align-items: center;
  gap: 12px;
}

.category-info-logo-img {
  width: 60px;
  height: 60px;
  border-radius: 8px;
  object-fit: cover;
  border: 2px solid #e4e7ed;
}

.category-info-logo-icon {
  font-size: 24px;
  color: #c0c4cc;
  width: 60px;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: #f5f7fa;
  border: 2px dashed #d9d9d9;
}

.category-info-logo-text {
  color: #606266;
  font-size: 14px;
}
</style> 